#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QObject>
#include <QQmlContext>
#include <signal.h>
#include <QProcess>
#include <QDate>
#include <QTime>
#include <execinfo.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include "QuickTool/QuickTool.h"
#include "Trans/Trans.h"
#include <QScreen>
//#ifdef QMAKE_GEN_TAOMACRO
//    #include "taoMacro.h"
//#endif
#include "s401model.h"
#include "sensorlist.h"
#include <QtQml>
#include "sensormodel.h"


static void printStackTrace()
{
    //Gpio::out(GPIO_PWR_CTRL_3V3_COMM, 0);
    QProcess sh;

    void *buf[200];
    size_t size = backtrace(buf, 200);
    char ** strings = backtrace_symbols(buf, 200);
    if (strings) {
        sh.start("sh", QStringList() << "-c" << "echo ---Start Stack trace > trace.txt");
        sh.waitForFinished();
        for (size_t i = 0; i < size; i++) {
            QString op =  QString("echo ") + "\""  + strings[i] + "\"" + " >> trace.txt";
            sh.start("sh", QStringList() << "-c" << op);
            sh.waitForFinished();
        }
        sh.start("sh", QStringList() << "-c" << "echo ---End Stack trace >> trace.txt");
        sh.waitForFinished();
    } else {
        sh.start("sh", QStringList() << "-c" << "echo no > trace.txt");
        sh.waitForFinished();
    }
}


static void sighandler(int signum) {
    //Gpio::out(GPIO_PWR_CTRL_3V3_COMM, 0);
    //printStackTrace();
    signal(signum, SIG_DFL);
    kill(getpid(), signum);
}


QtMessageHandler gDefaultHandler = NULL;
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QString strMsg("");
    switch(type)
    {
    case QtDebugMsg:
        strMsg = QString("[ Debug ]:");
        break;
    /*case QtInfoMsg:
        strMsg = QString(" Info :");
        break;*/
    case QtWarningMsg:
        strMsg = QString("[ Warning ]:");
        break;
    case QtCriticalMsg:
        strMsg = QString("[ Error ]:");
        break;
    case QtFatalMsg:
        strMsg = QString("[ H_Error ]:");
        break;
    default:
        strMsg = QString("[ Err ]:");
        break;
    }

    QString context_info = QString("[ File:(%1)  Line:(%2) ] :   ").arg(QString(context.file)).arg(context.line);
    QString current_date = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QString message = QString("%1 %2 %3 %4").arg(current_date).arg(strMsg).arg(context_info).arg(msg);


#if 0

    // lock
    static QMutex mutex;
    mutex.lock();

    // output to the file log.txt
    QFile file("D:\\log.txt");
    file.open(QIODevice::ReadWrite | QIODevice::Append);
    QTextStream stream(&file);
    stream << message << "\r\n";
    file.flush();
    file.close();

    // unlock
    mutex.unlock();

#endif
    // display debug info in IDE
    if (gDefaultHandler)
    {
        gDefaultHandler(type, context, message);
    }

}


int main(int argc, char *argv[])
{
    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

    if(QT_VERSION>=QT_VERSION_CHECK(5,6,0))
            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
    QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);

    QApplication app(argc, argv);

    app.setFont(QFont("microsoft yahei"));

//=================loging=============    
    gDefaultHandler = qInstallMessageHandler(myMessageOutput);//jr

//=================sinale handle=============
    struct sigaction act;
    memset(&act, 0, sizeof(act));

    act.sa_flags = SA_SIGINFO;
    act.sa_handler = &sighandler;
    sigaction(SIGINT, &act, 0);
    sigaction(SIGSEGV, &act, 0);
    sigaction(SIGILL, &act, 0);
    sigaction(SIGBUS, &act, 0);
    sigaction(SIGABRT, &act, 0);
    sigaction(SIGFPE, &act, 0);
//=================sinale handle end=============

    QQuickView view;
    QuickTool quickTool;
    Trans trans;

//    trans.beforeUiReady(view.rootContext(), "/home/jr/qtPJ/TaoQuick/examples/TaoQuickShow/Trans/");
    view.rootContext()->setContextProperty("imgPath", imgPath);
    view.rootContext()->setContextProperty("imgPATH", imgPATH);
    view.rootContext()->setContextProperty("conPATH", conPATH);


    qmlRegisterType<S401Model>("S401Modell", 1, 0, "S401Modell");
    qmlRegisterType<SensorList>("SensorList", 1, 0, "SensorList");
//    qmlRegisterType<SensorModel>("SensorModel", 1, 0, "SensorModel");
    qmlRegisterUncreatableType<SensorModel>("SensorModel",1,0,"SensorModel","can not instantiate MyCPPClass in qml");

    view.rootContext()->setContextProperty("isDebug", true);

    view.engine()->addImportPath(CusKeyImportPath);
//    view.engine()->addImportPath("qrc:/MyStyles");
    qputenv("QT_VIRTUALKEYBOARD_STYLE", "darkblue2");

    view.engine()->addImportPath(TaoQuickImportPath);
    view.rootContext()->setContextProperty("taoQuickImagePath", TaoQuickImagePath);
    view.rootContext()->setContextProperty("quickTool", &quickTool);

    QObject::connect(&view, &QQuickView::statusChanged, &view, [&](QQuickView::Status status) {
        if (status == QQuickView::Status::Ready) {
            trans.afterUiReady();
            quickTool.setRootObjet(view.rootObject());
        }
    });

    view.engine()->addImportPath("qrc:/SutoDisplay/imports");
    view.setSource(QUrl("qrc:/SutoDisplay/content/App.qml"));


    qDebug()<<CusKeyImportPath;

    if (!view.errors().isEmpty())
        return -1;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.show();

    QObject::connect(view.engine(), SIGNAL(quit()), &view, SLOT(close()));


    QScreen *screen=QApplication::primaryScreen ();
    QRect mm=screen->availableGeometry() ;
    int screen_width = mm.width();
    int screen_height = mm.height();
    qDebug()<<screen_width<<screen_height;

    qDebug()<<imgPATH;


    return app.exec();
}
